package com.xayy.mgt.service.impl;

import cn.kawins.base.result.CheckResult;
import cn.kawins.base.utils.BeanUtil;
import cn.kawins.base.utils.CollUtil;
import cn.kawins.mybatis.base.BaseServiceImpl;
import cn.kawins.mybatis.util.SnowflakeId;
import com.github.pagehelper.PageInfo;
import com.github.pagehelper.page.PageMethod;
import com.xayy.core.antlr4.utils.FunUtil;
import com.xayy.mgt.mapper.FunctionalIndicatorsMapper;
import com.xayy.mgt.mapper.NodeInfoMapper;
import com.xayy.mgt.model.AssociationParameter;
import com.xayy.mgt.model.BridgeParam;
import com.xayy.mgt.model.FunctionalIndicators;
import com.xayy.mgt.model.NodeTreeInfo;
import com.xayy.mgt.model.dto.NodeInfoDto;
import com.xayy.mgt.model.vo.FunctionalIndicatorVo;
import com.xayy.mgt.service.BridgeParamService;
import com.xayy.mgt.service.FunctionalIndicatorsService;
import com.xayy.mgt.service.NodeInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class FunctionalIndicatorsServiceImpl extends BaseServiceImpl<FunctionalIndicators>
    implements FunctionalIndicatorsService {

//    @Resource
//    private FunctionalIndicatorsService functionalIndicatorsService;
    @Resource
    private FunctionalIndicatorsMapper functionalIndicatorsMapper;
    @Autowired
    private BridgeParamService bridgeParamService;
//    @Autowired
//    private NodeInfoService nodeInfoService;

    @Autowired
    private NodeInfoMapper nodeInfoMapper;

    @Override
    @Transactional
    public CheckResult<Object> saveFunctionalIndicators(FunctionalIndicatorVo functionalIndicatorVo) {
        FunctionalIndicators functionalIndicators =
            BeanUtil.copyBean(functionalIndicatorVo, FunctionalIndicators.class);
        CheckResult<?> checkName = checkName(false, functionalIndicators);
        if (checkName.no()) {
            return CheckResult.fail(checkName.getCheckMsg());
        }
        CheckResult<?> checkCode = checkCode(false, functionalIndicators);
        if (checkCode.no()) {
            return CheckResult.fail(checkCode.getCheckMsg());
        }
        NodeTreeInfo nodeTreeInfo = nodeInfoMapper.selectByPrimaryKey(functionalIndicatorVo.getNodeId());
        CheckResult<?> checkSyntax = FunUtil.checkSyntax(nodeTreeInfo.getSatelliteId(),
            functionalIndicatorVo.getNodeId(), new Date(), functionalIndicatorVo.getCustomParam());
        if (checkSyntax.no()) {
            return CheckResult.fail(checkSyntax.getCheckMsg());
        }
        Long id = new SnowflakeId().genId("t_functional_indicators", "id");
        functionalIndicators.setId(id);
        this.insert(functionalIndicators);
        // 将功能项id和关联参数信息中间表添加
        List<Long> paramIds = functionalIndicatorVo.getParamIds();
        if (CollUtil.isNotEmpty(paramIds)) {
            List<BridgeParam> bridgeParams = new ArrayList<>();
            paramIds.forEach(x -> {
                BridgeParam bridgeParam = new BridgeParam();
                bridgeParam.setParentId(id);
                bridgeParam.setChildId(x);
                bridgeParam.setType(1);
                bridgeParams.add(bridgeParam);
            });
            bridgeParamService.insertList(bridgeParams);
        }

        return CheckResult.success("新增成功");
    }

    @Override
    @Transactional
    public CheckResult<Object> updateFunctionalIndicators(FunctionalIndicatorVo functionalIndicatorVo) {
        FunctionalIndicators functionalIndicators =
            BeanUtil.copyBean(functionalIndicatorVo, FunctionalIndicators.class);
        CheckResult<?> checkName = checkName(true, functionalIndicators);
        if (checkName.no()) {
            return CheckResult.fail(checkName.getCheckMsg());
        }
        CheckResult<?> checkCode = checkCode(true, functionalIndicators);
        if (checkCode.no()) {
            return CheckResult.fail(checkCode.getCheckMsg());
        }
        NodeTreeInfo nodeTreeInfo = nodeInfoMapper.selectByPrimaryKey(functionalIndicatorVo.getNodeId());
        CheckResult<?> checkSyntax = FunUtil.checkSyntax(nodeTreeInfo.getSatelliteId(),
            functionalIndicatorVo.getNodeId(), new Date(), functionalIndicatorVo.getCustomParam());
        if (checkSyntax.no()) {
            return CheckResult.fail(checkSyntax.getCheckMsg());
        }
        this.updateByIdSelective(functionalIndicators);
        // 将功能项id和关联参数信息中间表添加
        List<Long> paramIds = functionalIndicatorVo.getParamIds();
        if (CollUtil.isNotEmpty(paramIds)) {
            List<BridgeParam> bridgeParams = new ArrayList<>();
            paramIds.forEach(x -> {
                BridgeParam bridgeParam = new BridgeParam();
                bridgeParam.setParentId(functionalIndicators.getId());
                bridgeParam.setChildId(x);
                bridgeParam.setType(1);
                bridgeParams.add(bridgeParam);
            });
            bridgeParamService.delete(BridgeParam.builder().parentId(functionalIndicators.getId()).type(1).build());
            bridgeParamService.insertList(bridgeParams);
        }

        return CheckResult.success("修改成功");
    }

    @Override
    @Transactional
    public CheckResult<Object> deleteFunctionalIndicators(Long id) {
        this.deleteById(id);
        Example example = new Example(BridgeParam.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("childId", id);
        criteria.andEqualTo("childType", 1);
        criteria.andEqualTo("type", 3);
        Example.Criteria criteria1 = example.createCriteria();
        criteria1.andEqualTo("parentId", id);
        bridgeParamService.deleteByExample(example);
        return CheckResult.success("删除成功");
    }

    @Override
    @Transactional
    public CheckResult<Object> deleteFunctionalIndicators(List<Long> ids) {
        this.deleteByIds(ids);
        Example example = new Example(BridgeParam.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andIn("childId", ids);
        criteria.andEqualTo("childType", 1);
        criteria.andEqualTo("type", 3);
        Example.Criteria criteria1 = example.createCriteria();
        criteria1.andIn("parentId", ids);
        bridgeParamService.deleteByExample(example);
        return CheckResult.success("删除成功");
    }

    @Override
    public CheckResult<Object> deleteByNodeId(Long id) {
        List<FunctionalIndicators> select = select(FunctionalIndicators.builder().nodeId(id).build());
        if (CollUtil.isNotEmpty(select)) {
            List<Long> ids = select.stream().map(FunctionalIndicators::getId).collect(Collectors.toList());
            return deleteFunctionalIndicators(ids);
        }
        return CheckResult.success();
    }

    @Override
    public PageInfo<FunctionalIndicators> pageList(NodeInfoDto nodeInfoDto) {
        if (nodeInfoDto.getPage() == null || nodeInfoDto.getSize() == null) {
            Example example = new Example(FunctionalIndicators.class);
            example.createCriteria().andEqualTo("nodeId", nodeInfoDto.getParentId());
            List<FunctionalIndicators> functionalIndicatorsList = this.selectByExample(example);
            return new PageInfo<>(functionalIndicatorsList);
        }
        PageMethod.startPage(nodeInfoDto.getPage(), nodeInfoDto.getSize());
        List<FunctionalIndicators> functionalIndicatorsList = functionalIndicatorsMapper.pageList(nodeInfoDto);
        return new PageInfo<>(functionalIndicatorsList);
    }

    @Override
    public CheckResult<List<FunctionalIndicators>> getFunctionalIndicators(Long nodeId) {
        List<FunctionalIndicators> functionalIndicators = select(FunctionalIndicators.builder().nodeId(nodeId).build());
        return CheckResult.success(functionalIndicators);
    }

    @Override
    public CheckResult<Object> getInfo(Long id) {
        FunctionalIndicators functionalIndicators = selectById(id);
        if (BeanUtil.isEmpty(functionalIndicators)) {
            return CheckResult.fail("未获取到功能项信息");
        }
        FunctionalIndicatorVo functionalIndicatorVo =
            BeanUtil.copyBean(functionalIndicators, FunctionalIndicatorVo.class);
        List<BridgeParam> bridgeParams = bridgeParamService.select(BridgeParam.builder().parentId(id).build());
        List<Long> paramIds = bridgeParams.stream().map(BridgeParam::getChildId).collect(Collectors.toList());
        functionalIndicatorVo.setParamIds(paramIds);
        return CheckResult.success(functionalIndicatorVo);
    }

    /**
     * 校验同节点下得关联参数名称是否已存在
     *
     * @param isUpdate
     *            是否更新
     * @param functionalIndicators
     *            入参
     * @return 结果日志
     */
    private CheckResult<?> checkName(Boolean isUpdate, FunctionalIndicators functionalIndicators) {
        Example example = new Example(FunctionalIndicators.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("nodeId", functionalIndicators.getNodeId());
        criteria.andEqualTo("metricsName", functionalIndicators.getMetricsName());
        if (Boolean.TRUE.equals(isUpdate)) {
            criteria.andNotEqualTo("id", functionalIndicators.getId());
        }
        int i = selectCountByExample(example);
        if (i > 0) {
            return CheckResult.fail("指标名称：" + functionalIndicators.getMetricsName() + "已经存在");
        }
        return CheckResult.success();
    }

    /**
     * 校验同节点下得关联参数code是否已存在
     *
     * @param isUpdate
     *            是否更新
     * @param functionalIndicators
     *            入参
     * @return 结果日志
     */
    private CheckResult<?> checkCode(Boolean isUpdate, FunctionalIndicators functionalIndicators) {
        Example example = new Example(AssociationParameter.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("nodeId", functionalIndicators.getNodeId());
        criteria.andEqualTo("metricsCode", functionalIndicators.getMetricsCode());
        if (Boolean.TRUE.equals(isUpdate)) {
            criteria.andNotEqualTo("id", functionalIndicators.getId());
        }
        int i = selectCountByExample(example);
        if (i > 0) {
            return CheckResult.fail("指标代号：" + functionalIndicators.getMetricsCode() + "已经存在");
        }
        return CheckResult.success();
    }
}
